﻿using System;

namespace ZProto
{
    public class Utils
    {
        const byte BIT_1 = 0xFF;
        const ushort BIT_2 = 0xFF00;
        const uint BIT_3 = 0x00FF0000;
        const uint BIT_4 = 0xFF000000;
        const ulong BIT_5 = 0x000000FF00000000;
        const ulong BIT_6 = 0x0000FF0000000000;
        const ulong BIT_7 = 0x00FF000000000000;
        const ulong BIT_8 = 0xFF00000000000000;
        public static unsafe uint F2UI(float value)
        {
            return *(uint*)(&value);
        }
        public static unsafe float uint2float(uint value)
        {
            return *(float*)(&value);
        }
        public static unsafe ulong D2UL(double value)
        {
            return *(ulong*)(&value);
        }
        public static unsafe double ulong2double(ulong value)
        {
            return *(double*)(&value);
        }
        public static uint Endian(float value)
        {
            return Endian(F2UI(value));
        }
        public static ulong Endian(double value)
        {
            return Endian(D2UL(value));
        }
        public static uint Endian(int value)
        {
            return Endian((uint)(value));
        }
        public static uint Endian(uint value)
        {
            if (BitConverter.IsLittleEndian)
            {
                return value;
            }
            else
            {
                return ((value & BIT_1) << 24) |
                    ((value & BIT_2) << 8) |
                    ((value & BIT_3) >> 8) |
                    ((value & BIT_4) >> 24);
            }
        }
        public static ulong Endian(long value)
        {
            return Endian((ulong)(value));
        }
        public static ulong Endian(ulong value)
        {
            if (BitConverter.IsLittleEndian)
            {
                return value;
            }
            else
            {
                return ((value & BIT_1) << 56) |
                    ((value & BIT_2) << 40) |
                    ((value & BIT_3) << 24) |
                    ((value & BIT_4) << 8) |
                    ((value & BIT_5) >> 8) |
                    ((value & BIT_6) >> 24) |
                    ((value & BIT_7) >> 40) |
                    ((value & BIT_8) >> 56);
            }
        }
        public static ushort Endian(ushort value)
        {
            if (BitConverter.IsLittleEndian)
            {
                return value;
            }
            else
            {
                return (ushort)(((value & BIT_1) << 8) | ((value & BIT_2) >> 8));
            }
        }
        public static ushort Endian(short value)
        {
            return Endian((ushort)value);
        }
    }
}
